#include <string>
#include <vector>
#include <Windows.h>
#include <shlobj.h>
#include <tchar.h>
#include <Psapi.h>
#include <Knownfolders.h>
#include "path_utils.h"
#include  "text_util/string_proc.h"
namespace COMMON {
/*Common used KNOWNFOLDERID
* FOLDERID_RoamingAppData 		%APPDATA% (%USERPROFILE%\AppData\Roaming)
* FOLDERID_LocalAppData			%LOCALAPPDATA% (%USERPROFILE%\AppData\Local)
* FOLDERID_LocalAppDataLow		%USERPROFILE%\AppData\LocalLow
* FOLDERID_ProgramData			%ALLUSERSPROFILE% (%ProgramData%，%SystemDrive%\ProgramData)
* FOLDERID_ProgramFiles			%ProgramFiles% (%SystemDrive%\Program Files)
* FOLDERID_ProgramFilesX86		%ProgramFiles% (%SystemDrive%\Program Files(X86))
* FOLDERID_ProgramFilesCommon	%ProgramFiles%\Common Files
* FOLDERID_ProgramFilesCommonX64	%ProgramFilesX86%\Common Files
* FOLDERID_Profile				%USERPROFILE% (%SystemDrive%\Users\%USERNAME%)
* FOLDERID_Public				%PUBLIC% (%SystemDrive%\Users\Public)
* FOLDERID_PublicDocuments		%PUBLIC%\Documents
*/
std::string PATHUTILS::GetKnownFolder(KNOWNFOLDERID folderId, HANDLE userToken)
{
	PWSTR path = nullptr;
	if (SHGetKnownFolderPath(folderId, 0, userToken, &path) == S_OK) {
		std::string ret = StringProc::WStringToString(path);
		CoTaskMemFree(path);
		return ret;
	} else {
		return "";
	}
}
std::string PATHUTILS::GetUserAppDataRoamingFolder(HANDLE userToken)
{
	//C:\Users\username\AppData\Roaming
	return GetKnownFolder(FOLDERID_RoamingAppData, userToken);
}
std::string PATHUTILS::GetUserAppDataLocalFolder(HANDLE userToken)
{
	//C:\Users\username\AppData\Local
	return GetKnownFolder(FOLDERID_LocalAppData, userToken);
}
std::string PATHUTILS::GetCommonAppDataFolder(HANDLE userToken)
{
	//C:\ProgramData
	return GetKnownFolder(FOLDERID_ProgramData, userToken);
}
std::string PATHUTILS::GetPublicDocumentsFolder(HANDLE userToken)
{
	//C:\Users\Public\Documents
	return GetKnownFolder(FOLDERID_PublicDocuments, userToken);
}
std::string PATHUTILS::GetProgramFilesFolder(HANDLE userToken)
{
	//C:\ProgramFiles
	return GetKnownFolder(FOLDERID_ProgramFiles, userToken);
}
std::string PATHUTILS::GetProgramFilesX86Folder(HANDLE userToken)
{
	//C:\ProgramFiles (X86)
	return GetKnownFolder(FOLDERID_ProgramFilesX86, userToken);
}
std::string PATHUTILS::GetUserAppDataLocalLowFolder(HANDLE userToken)
{
	//C:\Users\username\AppData\LocalLow
	return GetKnownFolder(FOLDERID_ProgramFilesX86, userToken);
}
std::string PATHUTILS::GetSystemFolder()
{
	//C:\Windows
	TCHAR szPath[MAX_PATH] = {};
	SHGetSpecialFolderPath(NULL, szPath, CSIDL_WINDOWS, FALSE);
	return std::string(szPath);
}
bool PATHUTILS::IsSubDirectory(const std::string& pathA, const std::string& pathB)
{
	//Check whether pathA is sub directory of pathB
	return pathB.find(pathA, 0) == 0;
}
std::wstring PATHUTILS::GetProcessFilePath(DWORD pid)
{
	std::wstring fullName = {};
	WCHAR tempProcName[MAX_PATH] = { 0 };
	HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
	if (processHandle != NULL) {
		GetModuleFileNameExW(processHandle, NULL, tempProcName, MAX_PATH);
		CloseHandle(processHandle);
		processHandle = NULL;
		fullName = std::wstring(tempProcName);
	}
	return fullName;
}
}